<?php
class builds {
  function __construct() {
  }

  public function select() {
  
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->builds->rwd;
		if( !$rwd  ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'build_name';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
    
		switch( $sidx ) {
			case 'build_name': $sidx = 'bu.build_name'; break;
			case 'build_address': $sidx = 'bu.build_address'; break;
			case 'office_name': $sidx = 'of.build_name'; break;
			case 'build_id': $sidx = 'bu.build_id'; break;
		}
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
        if( $search )
        {
            if(isset($_REQUEST["build_id"]) && is_numeric($_REQUEST["build_id"]) ) {
				$whc[] = "bu.build_id=" . $db->quote($_REQUEST["build_id"]);
		    }
            
            if(isset($_REQUEST["build_name"]) && $_REQUEST["build_name"] != "") {
		    	$whc[] = "bu.build_name LIKE " . $db->quote("%".$_REQUEST["build_name"]."%");
            }

            if(isset($_REQUEST["build_address"]) && $_REQUEST["build_address"] != "") {
		    	$whc[] = "bu.build_address LIKE " . $db->quote("%".$_REQUEST["build_address"]."%");
            }
			
            if(isset($_REQUEST["office_name"]) && $_REQUEST["office_name"] != "") {
		    	$whc[] = "of.build_name LIKE " . $db->quote("%".$_REQUEST["office_name"]."%");
            }
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'build_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'build_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';
		
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);

        $join = " LEFT JOIN builds AS of ON of.build_id = bu.build_office_id ";
		
// Получаем количество записей с учетом фильтра
        $recset = $db->query( "SELECT COUNT(*) as count FROM builds AS bu " . $join . $whereclaus );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$count = $row['count'];
		$recset->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sqlreq =   "SELECT bu.build_id AS build_id, bu.build_name AS build_name, bu.build_address AS build_address, ".
							"bu.build_office_id AS build_office_id, of.build_name AS office_name ".
					"FROM builds AS bu " . $join . $whereclaus." ORDER BY ".$sidx." ".$sord.
		            " LIMIT ".$start.", ".$limit;

		$recset = $db->query($sqlreq);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $recset->fetch(PDO::FETCH_ASSOC)) {
			$data->rows[$i]['id'] = $row['build_id'];
			$data->rows[$i]['cell'] = array(
					$row['build_id'],
				    $row['build_name'],
				    $row['build_address'],
					$row['build_office_id'],
					$row['office_name']
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
  
  
  public function find() {
	$errcode = 0;
	$errmess = '';
    $data = array();
	
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Find - услуга общего пользования. Поэтому, маска должна быть READ_ANY
		$rwd = $_SESSION['priv']->builds->rwd;
		if( ( $rwd & PERM_BITS::READ_ANY ) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Проверяем данные
        $term   = isset($_REQUEST["term"]) ? trim(strip_tags($_REQUEST["term"])) : '';
        if ($term == '')
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
   
        $exactly   = (isset($_REQUEST["exactly"]) && strtolower($_REQUEST["exactly"]) == 'true' ) ? true : false;
		
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whs = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whs = 'build_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whs = 'build_user_id = '.$_SESSION['user_id'];
		else $whs = '1 = 0';
		
// Формируем запрос
		if( $exactly )
			$sqlreq =   "SELECT * FROM builds WHERE build_name = ".$db->quote($term).
					' AND '.$whs." ORDER BY build_name";
		else
			$sqlreq =   "SELECT * FROM builds WHERE ( build_name LIKE ".$db->quote("%".$term."%").
					" OR build_address LIKE ".$db->quote("%".$term."%").' ) AND '.$whs." ORDER BY build_name";
		
		$recset = $db->query($sqlreq);                  
        while( $row = $recset->fetch(PDO::FETCH_ASSOC) ) {
            $unit = new stdClass;
            $unit->value = $row['build_id'];
			
			$num = mb_strlen($term,'UTF-8');
			$pos = mb_stripos( $row['build_name'], $term, 0, 'UTF-8');
			if( !is_bool($pos) ) {
				$bterm = mb_substr($row['build_name'], $pos, $num, 'UTF-8');
				$name = preg_replace( '/'.$bterm.'/u', '<b>'.$bterm.'</b>', $row['build_name'] );				
			} else $name = $row['build_name'];
			$pos = mb_stripos( $row['build_address'], $term, 0, 'UTF-8');
			if( !is_bool($pos) ) {
				$bterm = mb_substr($row['build_address'], $pos, $num, 'UTF-8');
				$addr = preg_replace( '/'.$bterm.'/u', '<b>'.$bterm.'</b>', $row['build_address'] );				
			} else $addr = $row['build_address'];
			
            $unit->name = $name;
			$unit->address = $addr;
            $data[] = $unit;
        }
        $recset->closeCursor();
 
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}
 
	return array('errcode'=>$errcode,'errmess'=>$errmess, 'data'=>$data);
  }
  
  
  public function insert() {

    $build_name = isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $build_address = isset($_POST['build_address']) ? trim(strip_tags($_POST['build_address'])) : '';
    $build_office_id = isset($_POST['build_office_id']) ? trim(strip_tags($_POST['build_office_id'])) : '';
    $office_name = isset($_POST['office_name']) ? trim(strip_tags($_POST['office_name'])) : '';
	
	if( !$build_office_id ) $build_office_id = 0;

	$errcode = 0;
	$errmess = '';
    try
    {
// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$build_user_id = $_SESSION['user_id'];

//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->builds->rwd;
		if( ($rwd & PERM_BITS::WRITE_OWN) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Все ли данные переданы
		$errdata = "";
		if( $build_name == '' ) $errdata = "Не указано имя объекта.";
		if( $build_address == '' ) $errdata .= ($errdata?'<br>':'').'Не указан адрес объекта.';
		
		if( $build_office_id ) {
			if( !ctype_digit($build_office_id) || $office_name == '' )
				$errdata .= ($errdata?'<br>':'').'Неправильно указан идентификатор офиса.';
			else {
				$rs = $db->query('SELECT build_name, build_office_id FROM builds WHERE build_id = '.$db->quote($build_office_id));                  
				$row = $rs->fetch(PDO::FETCH_ASSOC);
				if( !$row || $row['build_name'] != $office_name || $row['build_office_id'] > 0 ) {
					$errdata .= ($errdata?'<br>':'').'Неправильно указан идентификатор офиса.';
				}
				$rs->closeCursor();
			}
		}
		
		if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть объект с указаным именем уже существует
		$build_key = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $build_name, 'UTF-8') );
		$recset = $db->query('SELECT build_name FROM builds WHERE build_key = '.$db->quote($build_key));                  
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			$old_build_name = $row['build_name'];
			throw new Exception('Объект с именем "'.$old_build_name.'" уже существует.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =	"INSERT INTO builds ( build_name, build_address, build_office_id, build_key, build_user_id ) ".
					"VALUES (".	$db->quote($build_name).", ".$db->quote($build_address).", ".
							$db->quote($build_office_id).", ".$db->quote($build_key).", ".$db->quote($build_user_id).")";
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  public function update() {
	
    $build_id = isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $build_name = isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $build_address = isset($_POST['build_address']) ? trim(strip_tags($_POST['build_address'])) : '';
    $build_office_id = isset($_POST['build_office_id']) ? trim(strip_tags($_POST['build_office_id'])) : '';
    $office_name = isset($_POST['office_name']) ? trim(strip_tags($_POST['office_name'])) : '';
	
	if( !$build_office_id ) $build_office_id = 0;

	$errcode = 0;
	$errmess = '';
    try
    {
// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$build_user_id = $_SESSION['user_id'];

// Есть ли разрешение на изменение чьей либо записи
		$rwd = $_SESSION['priv']->builds->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Все ли данные переданы
		$errdata = "";
		if( $build_id == '' ) $errdata = "Не указан идентификатор объекта.";
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'')."Не указано шифр объекта.";
		if( $build_address == '' ) $errdata .= ($errdata?'<br>':'').'Не указан адрес объекта.';

		if( $build_office_id ) {
			if( !ctype_digit($build_office_id) || $office_name == '' )
				$errdata .= ($errdata?'<br>':'').'Неправильно указан идентификатор офиса.';
			else {
				$rs = $db->query('SELECT build_name, build_office_id FROM builds WHERE build_id = '.$db->quote($build_office_id));                  
				$row = $rs->fetch(PDO::FETCH_ASSOC);
				if( !$row || $row['build_name'] != $office_name  || 
					$row['build_office_id'] > 0 || $build_office_id == $build_id ) {
					$errdata .= ($errdata?'<br>':'').'Неправильно указан идентификатор офиса.';
				}
				$rs->closeCursor();
			}
		}
		
		if( $errdata ) throw new Exception($errdata, 1);
		
// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'build_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'build_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND build_id = '.$db->quote($build_id);
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM builds WHERE '.$where.' LIMIT 1';
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row['count'] ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Может быть объект с указаным именем уже существует
		$build_key = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $build_name, 'UTF-8') );
		$recset = $db->query('SELECT build_name FROM builds WHERE build_key = '.$db->quote($build_key).' AND '.
			'build_id != '.$db->quote($build_id));                  
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			$old_build_name = $row['build_name'];
			throw new Exception('Объект с именем "'.$old_build_name.'" уже существует.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq = 	'UPDATE builds SET '.
					'build_name = '.$db->quote($build_name).', '.
					'build_address = '.$db->quote($build_address).', '.
					'build_office_id = '.$db->quote($build_office_id).', '.
					'build_key = '.$db->quote($build_key).' '.
					'WHERE build_id = '.$db->quote($build_id);

		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
  
  
  public function delete() {
    $errmess = "";
	$errcode = 0;
		
    $build_ids = (isset($_REQUEST['id']) && $_REQUEST['id'] != '') ?
        explode(",", $_REQUEST["id"], 100) : array();

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли разрешение на удаление хоть какой либо записи
		$rwd = $_SESSION['priv']->builds->rwd;
		if( ($rwd & PERM_BITS::DELETE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
        if (!Tools::is_numeric_array( $build_ids ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$build_id_list = implode(',', $build_ids);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на удаление этих записей
		if( $rwd & PERM_BITS::DELETE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::DELETE_GRP ) 
			$where = 'build_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::DELETE_OWN ) $where = 'build_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND build_id IN ('.$build_id_list.')';
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM builds WHERE '.$where;
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row['count'] != count($build_ids) ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Проверяем, есть ли эти коды объектов в таблицах

		$sqlreq =   "( SELECT 'Расходы по контрагентам' as a FROM `incoming` WHERE inc_build_id IN (".$build_id_list.") LIMIT 1 ) ".
					"UNION ".
					"( SELECT 'Приход по клиентам' as a  FROM `outgoing` WHERE out_build_id IN (".$build_id_list.") LIMIT 1 ) ".
					"UNION ".
					"( SELECT 'Землеотведение' as a  FROM `parcel` WHERE par_build_id IN (".$build_id_list.") LIMIT 1 ) ".
					"UNION ".
					"( SELECT 'Оъекты, офис' as a  FROM `builds` WHERE build_office_id IN (".$build_id_list.") LIMIT 1 )";
		$recset = $db->query($sqlreq);
		$errdata = '';
		while( $row = $recset->fetch(PDO::FETCH_ASSOC) ) {
			$errdata .= ($errdata?', ':'')."'".$row['a']."'"; 
		}
		if( $errdata != '' )
			throw new Exception( "Удаляемые объекты задействованы в следующих документах:<br>".$errdata, 1);

// Удаляем записи из справочника
        $sqlreq = "DELETE FROM builds WHERE build_id IN (".$build_id_list.")";
        $db->exec($sqlreq);
	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
}
?>